//
//  glutils.m
//  myfistopengl
//
//  Created by huiti123 on 2017/3/30.
//  Copyright © 2017年 wtw. All rights reserved.
//

#import "glutils.h"

#import <OpenGLES/ES2/gl.h>

@implementation glutils



+ (GLuint)loadShader:(GLenum)type withFilepath:(NSString *)shaderFilePath
{
    NSError *error;
    NSString *shaderString = [NSString stringWithContentsOfFile:shaderFilePath encoding:NSUTF8StringEncoding error:&error];
    if (!shaderString) {
        NSLog(@"Error: loading shader file: %@ %@", shaderFilePath, error.localizedDescription);
    }
    
    return [self loadShader:type withString:shaderString];
}


+ (GLuint)loadShader:(GLenum)type withString:(NSString *)shaderString
{
   
    GLuint shader = glCreateShader(type);
    if (shader == 0) {
        NSLog(@"Error: failed to create shader.");
        return 0;
    }
    
    // Load the shader source
    const char *shaderStringUTF8 = [shaderString UTF8String];
    
    glShaderSource(shader, 1, &shaderStringUTF8, NULL);
    glCompileShader(shader);
    
    GLint compiled_result = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled_result);
    
    if(!compiled_result){
        GLint infoLen  = 0 ;{
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
            if(infoLen > 0){
                char *log = malloc(sizeof(char) *infoLen);
                glGetShaderInfoLog(shader, infoLen, NULL, log);
                NSLog(@"compile shader erro info = %s",log);
                free(log);
            }
        }
        glDeleteShader(shader);
        return 0;
    }
    
    return shader;
}

+(GLuint)loadProgram:(NSString *)vertexShaderStr withFragmentShaderStr:(NSString*)fragmentShaderStr
{
    
    GLuint vertexShader = [self loadShader:GL_VERTEX_SHADER withString:vertexShaderStr];
    if(vertexShader == 0){
        return 0;
    }
    
    GLuint fragmentShader = [self loadShader:GL_FRAGMENT_SHADER withString:fragmentShaderStr];
    

    if(fragmentShader == 0){
        glDeleteShader(vertexShader);
        return 0;
    }
    
    GLuint program = glCreateProgram();
    if (program == 0) {
        return 0;
    }
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    
    glLinkProgram(program);
    
    GLint linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (linked == 0) {
        GLint infoLen;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
        if(infoLen > 0){
            char *log = malloc(sizeof(char) *infoLen);
            glGetProgramInfoLog(program, infoLen, NULL, log);
            NSLog(@"link program erro info = %s",log);
            free(log);
        }
        glDeleteProgram(program);
        return 0;
    }
    
    return program;
}

+(GLuint)loadProgram:(NSString *)vertexShaderFile withFragmentShaderFile:(NSString*)fragmentShaderFile{
    GLuint vertexShader = [self loadShader:GL_VERTEX_SHADER withFilepath:vertexShaderFile];
    if(vertexShader == 0){
        return 0;
    }
    
    GLuint fragmentShader = [self loadShader:GL_FRAGMENT_SHADER withString:fragmentShaderFile];
    
    if(fragmentShader == 0){
        glDeleteShader(vertexShader);
        return 0;
    }
    
    GLuint program = glCreateProgram();
    if (program == 0) {
        return 0;
    }
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    
    glLinkProgram(program);
    
    GLint linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (linked != 0) {
        GLint infoLen;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
        if(infoLen > 0){
            char *log = malloc(sizeof(char) *infoLen);
            glGetProgramInfoLog(program, infoLen, NULL, log);
            NSLog(@"link program erro info = %s",log);
            free(log);
        }
        glDeleteProgram(program);
        return 0;
    }
    
    return program;
    
}




@end
